---
section: Getting Started
title: Upgrade Guide
slug: /docs/upgrade-guide/
order: 4
---

# Upgrade guide

Upgrading from xstyled from v1.x to v3.0.

<carbon-ad />

# From v2.x to v3.x

xstyled v3 is focused on features.

## Object states

States are now similar to breakpoints, they are specified using object syntax:

```js
<x.button color={{ _: 'red-500', hover: 'red-300' }} />
```

They can be nested:

```js
// Mixed screens and states
<x.button color={{ _: 'red-600', md: { _: 'red-500', hover: 'red-300' } }} />
// Nested states
<x.div bg={{ first: { odd: 'blue' } } } />
```

And they are configurable in theme:

```js
export const theme = {
  states: {
    hover: '&:hover',
    // ...
  },
}
```

Learn more in [states documentation](/docs/hover-focus-other-states/).

## Plugins API

xstyled can now be fully extended with plugins using a `xstyled.config.js`:

```js
import { createCss, system, compose } from '@xstyled/...'
import { borderInline } from './utilities/border-inline'

export const { css, styled, x, createGlobalStyle } = createCss(
  compose(system, borderInline),
)
```

Learn more in [documentation](/docs/adding-new-utilities/).

## New text utility

A new text utility has been added. It is similar to `fontSize` excepts that it defines both `font-size` and `line-height`. It is customizabled to handle all your typography styles.

Learn more in [text utility documentation](/docs/text/).

## New utilities

`animationDuration`, `animationTimingFunction` and `maskSize` have been added to the core.

## Remove specificity

xstyled was using a trick to ensure props were more specific than component style. The props were injected in a `&&`, so the class was duplicated and the specificity increased. In v3, props are now injected in the correct order, it means this specificity is not longer required.

## New `multiple` option in style

You can now use `multiple` to declare style that accepts multiple styles separated by a comma. For example, `box-shadow`:

```js
<x.div boxShadow="light-shadow, big-shadow" />
```

## Breaking changes

### No prefixed states

States were prefixed props in v2. You can use this regular expression to find state props in your code:

```
((motionSafe|motionReduce|first|last|odd|even|visited|focusWithin|hover|focus|focusVisible|focusWithin|active|disabled|placeholder|checked)[A-Z])[A-Za-z]+=
```

### `Box` has been removed

`Box` component is no longer available, you can safely replace it by `x.div`.

### `cssProperty` option of `style` becomes `css`

Since the [`css` accepts a mixin](/docs/adding-new-utilities/#generate-arbitrary-style), `cssProperty` was no longer a good name.

### `getBreakpoints` becomes `getScreens` and `useBreakpoints` becomes `useScreens`

In v1, theme section handling screens was named `breakpoints`, since v2 theme section is now `screens`. For consistency `getBreakpoints` becomes `getScreens` and `useBreakpoints` becomes `useScreens`.

### `th.timingFunctions` becomes `th.timingFunction`

Every `th.*` utilities are singular, `th.timingFunctions` was a mistake.

### `x.extend` and `createX` are gone

Use `createCss` instead.

### TypeScript theme bindings

Be sure to correctly extend xstyled theme and to follow [TypeScript guide](/docs/typescript/).

# From v1.x to v2.x

xstyled v2 is the new major version since v1 of xstyled released in May 2019.

We know that xstyled is in the core of your project and that the migration could be difficult. For that purpose, we minimized the number of changes between the two versions, there is only few breaking changes.

## New philosophy

xstyled exposes `x` namespace to easily create declarative components and style your website without writing CSS. The new version push this approach at the edge. The v2 still supports magic styled components, they are even better than before!

```js
import { x } from '@xstyled/...'

function Button() {
  return (
    <x.button
      type="button"
      color="white"
      transition
      bg={{ _: 'emerald-500', hover: 'emerald-800' }}
    >
      Upgrade
    </x.button>
  )
}
```

You don't have to choose between `x` or `styled`, the two approaches are supported. Feel free to use one or another or to mix both (like me).

## Breaking changes

### Emotion v11

xstyled v2 works with Emotion v11, if you use xstyled v1 with Emotion, please read [the migrate guide from Emotion v10 to Emotion v11](https://emotion.sh/docs/migrating-to-emotion-10#incremental-migration) first.

### No more default `space`

xstyled v1 had default `space` built-in, in v2 `space` are now located in default theme and are slightly different from v1. Two options:

- **If you have customized `space` in your theme:**

Good news! You don't have to do anything, just keep your them in v2.

- **If you have not customized `space` in your theme:**

Use old `space` in your theme:

```js
const theme = {
  space: [0, 4, 8, 16, 24, 48, 96, 144, 192, 240],
}
```

- **If you were not using any theme:**

Read [customize theme documentation](/docs/theme/) to learn how to create a theme.

### `gridGap` becomes `gap`

To follow the [new specification](https://developer.mozilla.org/en-US/docs/Web/CSS/gap), `gridGap` becomes `gap`.

- **If you use `gridGap` in your project:**

Replace it by `gap`.

### `width` becomes `w`, `height` becomes `h`

To reduce conflict between image attributes `width` and `height`, only `w` and `h` are now usable to define CSS properties `width` and `height`.

- **If you use `width` or `height` in your project:**

Replace it by `w` and `h`.

### No more `size` utility

To reduce conflict between [input attribute `size`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-size), size .

- **If you use `size` in your project:**

Replace it by `w` + `h`.

### No more `forwardedAs`

Everything is now simplified, you don't have to worry about `forwardedAs` any more, `as` works everywhere.

- **If you use `forwardedAs`:**

- Replace it by `as`.

### Utilities groups reorganization

xstyled v2 exposes lot of new utilities, to be more consistent, utilities groups have been completely changed.

- **If you use utility groups like `backgrounds`, `basics`, `borders`, `flexboxes`, `grids`, `layout`, `positioning`, `shadows`, `space`, `svg`, `typography` or `xgrids`:**

You have to pick new groups of utilities or single utilities. Read [how to create utilities](/docs/adding-new-utilities/) to learn more about it.

### Breakpoints

xstyled v2 now uses the same breakpoints as Tailwind, it was using Bootstrap's one but landscape have changed and those from Tailwind are actually more realistic. Also, breakpoints are now read from `screens` theme key.

- **If you use breakpoints and does not define them:**

Add xstyled v1 breakpoints:

```js
const theme = {
  screens: { xs: 0, sm: 576, md: 768, lg: 992, xl: 1200 },
}
```

- **If you already use your own breakpoints:**

Migrate them to `screens`:

```diffjs
  const theme = {
-   breakpoints: { xs: 0, md: 800 },
+   screens: { xs: 0, md: 800 },
  }
```

### No more `variant` utility

`variant` utility was confusing and not really helpful, xstyled v2 encourages to use the `x.*` syntax, so it is no longer required.

- **If you want use `variant` utility and you want to get it back:**

Add `variant` utility in your codebase:

```js
import { getThemeValue, merge, warn, is, assign } from '@xstyled/util'

const variant =
  ({ key = null, default: defaultValue, variants = {}, prop = 'variant' }) =>
  (props) => {
    const themeVariants = is(key) ? getThemeValue(props, key) : null
    const computedVariants = merge(assign({}, variants), themeVariants)
    const value = props[prop] !== undefined ? props[prop] : defaultValue
    const result = getThemeValue(props, value, computedVariants)
    warn(is(result), `variant "${value}" not found`)
    return result
  }
```
